-
Notifications
You must be signed in to change notification settings - Fork 23
add support for QuerySet.annotate() #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
85c4206
to
e4cc20d
Compare
e4cc20d
to
0dd8d6b
Compare
django_mongodb/query.py
Outdated
cursor.limit(int(self.query.high_mark - self.query.low_mark)) | ||
return cursor | ||
pipeline.append({"$limit": self.query.high_mark - self.query.low_mark}) | ||
return self.collection.aggregate(pipeline) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I saw this in other PR. Is there any order to follow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just rebased this on that PR (you can see it's the first commit here) to make sure everything works with that change. I'll merge that PR first, then rebase this again so this change disappears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, only a minor question about the converter indexing.
backend_converters = self.connection.ops.get_db_converters(column) | ||
field_converters = column.field.get_db_converters(self.connection) | ||
if backend_converters or field_converters: | ||
converters[column.target.column] = backend_converters + field_converters | ||
converters[name] = backend_converters + field_converters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Django sql compiler uses an index. Like an integer and maintain the order.
https://github.com/mongodb-forks/django/blob/mongodb-5.0.x/django/db/models/sql/compiler.py#L1483
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, however, MongoDB returns a document of (unordered?) fields, hence we may need to use the key lookup approach (or at least this was the reason for the original implementation in Django Mongo Engine + Python 2). Since Python 3.7 dictionaries are guaranteed to be insertion ordered. Not sure how the MongoDB server handles field ordering though (does it match the order of $project
)? Could be checked but the idea is orthogonal to this PR which just builds on the existing implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. Great job switching this to use Aggregation!
django_mongodb/base.py
Outdated
mongo_aggregates = { | ||
"exact": lambda a, b: {"$eq": [a, b]}, | ||
"gt": lambda a, b: {"$gt": [a, b]}, | ||
"gte": lambda a, b: {"$gte": [a, b]}, | ||
"lt": lambda a, b: {"$lt": [a, b]}, | ||
"lte": lambda a, b: {"$lte": [a, b]}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you need the iexact, startswith, endswith equivalents here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's possible those lookups could be used as annotations, but I'm not sure the Django test suite covers it. I wouldn't worry about it unless we get a bug report.
51a65b5
to
06f34f8
Compare
While triaging the annotations tests, I found few more bugs which are fixed in the first two of the last three commits, so I'd appreciate it if you could review those. |
django_mongodb/base.py
Outdated
@@ -73,6 +91,13 @@ class DatabaseWrapper(BaseDatabaseWrapper): | |||
"regex": lambda val: re.compile(val), | |||
"iregex": lambda val: re.compile(val, re.IGNORECASE), | |||
} | |||
mongo_aggregates = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 In this PR add support for annotates, so Why is mongo_aggregates the name? shouldn't it be mongo_annotates? IMO aggregates sounds like $sum, $avg, and all this kind of group by operators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I called it mongo_functions
but renamed it because https://www.mongodb.com/docs/manual/reference/operator/aggregation/lt/ describes it as "aggregation". Maybe it should be mongo_aggregations
. I'm not sure the precise difference between aggregate and aggregation!
@@ -54,7 +54,25 @@ class DatabaseWrapper(BaseDatabaseWrapper): | |||
"TimeField": "date", | |||
"UUIDField": "string", | |||
} | |||
# Django uses these operators to generate SQL queries before it generates | |||
# MQL queries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate on this? Why does SQL get generated if we're running a mongodb query?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has to do with how this library hooks in to the query generation process. See also:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Also fix annotating with Value().
06f34f8
to
db3b2d0
Compare
No description provided.